package com.grq.mis.service;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.grq.mis.dao.DepartmentDao;
import com.grq.mis.dao.RoleDao;
import com.grq.mis.dao.UserDao;
import com.grq.mis.dao.UserRoleDao;
import com.grq.mis.entity.Department;
import com.grq.mis.entity.Role;
import com.grq.mis.entity.User;
import com.grq.mis.entity.UserRole;
import com.grq.mis.exception.BusinessException;
import com.grq.mis.exception.ResultEnum;
import com.grq.mis.model.sys.Me;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Transactional
@Service
public class UserService extends BaseService<User>{

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private DepartmentDao departmentDao;

    public void register(User model) {

        User user = userDao.createLambdaQuery().andEq(User::getUsername,model.getUsername()).single();
        if (user != null){
            throw new BusinessException(ResultEnum.USERNAME_IS_EXIST);
        }

        Department department = departmentDao.single(model.getDepartmentId());
        if (department == null){
            throw new BusinessException(ResultEnum.DEPARTMENT_IS_NULL);
        }
        if (department.getIsDisable()){
            throw new BusinessException(ResultEnum.DEPARTMENT_IS_NULL);
        }

        user = new User();
        user.setUsername(model.getUsername());
        String password = DigestUtil.bcrypt(model.getPassword());
        user.setPassword(password);
        user.setName(model.getName());
        user.setCompany(model.getCompany());
        user.setPhone(model.getPhone());
        user.setCreateTime(new Date());
        user.setIsDisable(false);
        user.setDepartmentId(model.getDepartmentId());
        userDao.insert(user);

        UserRole ur = new UserRole(user.getId(),6L);
        userRoleDao.insert(ur);
    }

    public void addUser(User user, Long[] roleIds) {

        long count = userDao.createLambdaQuery().andEq(User::getUsername, user.getUsername()).count();
        if (count > 0) {
            throw new BusinessException(ResultEnum.USERNAME_IS_EXIST);
        }
        long count2 = userDao.createLambdaQuery().andEq(User::getPhone, user.getPhone()).count();
        if (count2 > 0) {
            throw new BusinessException(ResultEnum.USER_PHONE_IS_EXIST);
        }

        if (user.getDepartmentId() != 0){
            Department department = departmentDao.single(user.getDepartmentId());
            if (department == null){
                throw new BusinessException(ResultEnum.DEPARTMENT_IS_NULL);
            }
            if (department.getIsDisable() == true){
                throw new BusinessException(ResultEnum.DEPARTMENT_IS_NULL);
            }
        }else{
            user.setDepartmentId(null);
        }

        String password = DigestUtil.bcrypt(user.getPassword());
        user.setPassword(password);
        user.setCreateTime(new Date());
        user.setIsDisable(false);
        user.setWechatId(null);
        userDao.insert(user);

        if (roleIds != null && roleIds.length > 0) {
            List<Role> roles = roleDao.createLambdaQuery().andIn(Role::getId, Arrays.asList(roleIds)).select();
            List<UserRole> userRoles = new ArrayList<>();
            for (Role role : roles) {
                userRoles.add(new UserRole(user.getId(), role.getId()));
            }
            userRoleDao.insertBatch(userRoles);
        }
    }

    public void updateUser(User model, Long[] roleIds) {

        User user = userDao.single(model.getId());
        if (user == null) {
            throw new BusinessException(ResultEnum.USER_IS_NULL);
        }

        long count2 = userDao.createLambdaQuery().andEq(User::getPhone, user.getPhone()).andNotEq(User::getId,model.getId()).count();
        if (count2 > 0) {
            throw new BusinessException(ResultEnum.USER_PHONE_IS_EXIST);
        }

        if (model.getDepartmentId() != 0){
            Department department = departmentDao.single(model.getDepartmentId());
            if (department == null){
                throw new BusinessException(ResultEnum.DEPARTMENT_IS_NULL);
            }
            if (department.getIsDisable() == true){
                throw new BusinessException(ResultEnum.DEPARTMENT_IS_NULL);
            }
            user.setDepartmentId(department.getId());
        }else{
            user.setDepartmentId(null);
        }

        user.setName(model.getName());
        user.setCompany(model.getCompany());
        user.setPhone(model.getPhone());
        user.setIsDisable(model.getIsDisable());
        userDao.updateById(user);

        userRoleDao.createLambdaQuery().andEq(UserRole::getUserId, user.getId()).delete();
        if (roleIds != null && roleIds.length > 0) {
            List<Role> roles = roleDao.createLambdaQuery().andIn(Role::getId, Arrays.asList(roleIds)).select();
            List<UserRole> userRoles = new ArrayList<>();
            for (Role role : roles) {
                userRoles.add(new UserRole(user.getId(), role.getId()));
            }
            userRoleDao.insertBatch(userRoles);
        }
    }

    public void reset(Long id) {
        User user = userDao.single(id);
        if (user == null) {
            throw new BusinessException(ResultEnum.USER_IS_NULL);
        }

        String pwd = "123456";
        user.setPassword(DigestUtil.bcrypt(pwd));
        userDao.updateById(user);
    }

    public void password(Me me, String oldPassword, String newPassword) {
        User user = userDao.single(me.getId());
        if (user == null) {
            throw new BusinessException(ResultEnum.USER_IS_NULL);
        }

        String oldHex = user.getPassword();
        if (DigestUtil.bcryptCheck(oldPassword, oldHex) == false) {
            throw new BusinessException(ResultEnum.PASSWORD_ERROR, "旧密码错误");
        }

        String newHex = DigestUtil.bcrypt(newPassword);
        user.setPassword(newHex);
        userDao.updateById(user);
    }

    public void updateMyInfo(User model, Me me) {

        User user = userDao.single(me.getId());
        if (user == null) {
            throw new BusinessException(ResultEnum.ERROR,"用户信息不存在");
        }

        user.setName(model.getName());
        user.setCompany(model.getCompany());
        user.setPhone(model.getPhone());
        userDao.updateById(user);

        me.setName(model.getName());
        me.setPhone(model.getPhone());
        me.setCompany(model.getCompany());

        StpUtil.getSession().set("me",me);

    }
}
